/*
 * mmanager.go
 * 
 * Copyright 2013 Mykola Dvornik <mykola.dvornik@gmail.com>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 * 
 * 
 */

package mmanager

import (
	"code.google.com/p/semargl4/io"
	plog "code.google.com/p/semargl4/logger"
)

const BUFFERSIZE = int64(2 * 1024 * 1024 * 1024) // the default buffer size is 2 GigaCells = 8 Gigabytes

var hostEnum = map[string]int64{"HDD": int64(0), "RAM": int64(1)}

type MManager struct {
	FileNames []string
	Topology  []int64
	Command   chan int
	InChan    []chan io.In
	OutChan   []chan io.Out
}

func NewMemoryManager(filenames []string, topology []int64) *MManager {
	mm := new(MManager)
	mm.FileNames = filenames
	mm.Topology = []int64{int64(len(mm.FileNames)), topology[0], topology[1], topology[2]}
	mm.InChan = make([]chan io.In, mm.Topology[0])
	mm.OutChan = make([]chan io.Out, mm.Topology[0])
	for i := int64(0); i < mm.Topology[0]; i++ {
		mm.InChan[i] = make(chan io.In, 1)
		mm.OutChan[i] = make(chan io.Out, 1)
	}
	return mm
}

func (mm *MManager) Run() {
	plog.Print("Starting Memory Manager for: ", mm.Topology, " ...")
	for i := int64(0); i < mm.Topology[0]; i++ {
		go io.Gather(mm.FileNames[i],
			mm.InChan[i],
			mm.OutChan[i],
			i)
	}
	plog.Print("Memory Manager Waiting for Commands...")
	for i := int64(0); i < mm.Topology[0]; i++ {
		<-mm.OutChan[i]
	}
}

//~ func (mm *MManager) GetBlock(block BBox) []byte {
//~ 
//~ }

func (mm *MManager) Stop() {
	plog.Print("Stopping Memory Manager...")
	for i := int64(0); i < mm.Topology[0]; i++ {
		mm.InChan[i] <- io.In{Mode: -1}
	}
	plog.Print("Done.")
}
